{% from "header.jinja" import header %}

"""{{ header() }}"""

{% from "rest/_param.py.jinja" import endpoint_params, endpoint_raw_params, endpoint_model_params %}
{% from "rest/_response.py.jinja" import build_response_type %}
{% from "rest/_request.py.jinja" import build_request, build_request_params %}

from __future__ import annotations

from weakref import ref
from typing_extensions import Annotated
from typing import TYPE_CHECKING, Dict, Literal, Optional, overload

from pydantic import BaseModel, Field

from githubkit.typing import Missing
from githubkit.utils import exclude_unset, UNSET
from githubkit.compat import model_dump, type_validate_python

if TYPE_CHECKING:
    from githubkit import GitHubCore
    from githubkit.response import Response
    {% for endpoint in endpoints %}

    {# param types #}
    {% for param in endpoint.parameters %}
    {% for import_ in param.get_param_imports() %}
    {{ import_ }}
    {% endfor %}
    {% endfor %}

    {# request body type #}
    {% if endpoint.request_body %}
    {% for import_ in endpoint.request_body.body_schema.get_param_imports() %}
    {{ import_ }}
    {% endfor %}
    {# request body property types #}
    {% for model in endpoint.request_body.allowed_models %}
    {% for prop in model.properties %}
    {% for import_ in prop.get_param_imports() %}
    {{ import_ }}
    {% endfor %}
    {% endfor %}
    {% endfor %}
    {% endif %}

    {# response model #}
    {% if endpoint.success_response and endpoint.success_response.response_schema %}
    {% for import_ in endpoint.success_response.response_schema.get_using_imports() %}
    {{ import_ }}
    {% endfor %}
    {% endif %}
    {% endfor %}

class {{ pascal_case(tag) }}Client:
    _REST_API_VERSION = "{{ rest_api_version }}"

    def __init__(self, github: GitHubCore):
        self._github_ref = ref(github)

    @property
    def _github(self) -> GitHubCore:
        if g := self._github_ref():
            return g
        raise RuntimeError(
            "GitHub client has already been collected. "
            "Do not use this client after the client has been collected."
        )

    {% for endpoint in endpoints %}
    {% if endpoint.request_body and endpoint.request_body.allowed_models %}
    {# generate raw data overload #}
    @overload
    def {{ endpoint.name }}(
        self,
        {{ endpoint_raw_params(endpoint) | indent(8) }}
    ) -> {{ build_response_type(endpoint.success_response) }}:
        ...

    {# generate model data overload #}
    {% for model in endpoint.request_body.allowed_models %}
    @overload
    def {{ endpoint.name }}(
        self,
        {{ endpoint_model_params(endpoint, model) | indent(8) }}
    ) -> {{ build_response_type(endpoint.success_response) }}:
        ...

    {% endfor %}
    {% endif %}
    def {{ endpoint.name }}(
        self,
        {{ endpoint_params(endpoint) | indent(8) }}
    ) -> {{ build_response_type(endpoint.success_response) }}:
        {% if endpoint.external_docs %}
        """See also: {{ endpoint.external_docs }}"""

        {% endif %}
        {{ build_request(endpoint) | indent(8) }}
        return self._github.request(
            {{ build_request_params(endpoint) | indent(12) }}
        )

    {% if endpoint.request_body and endpoint.request_body.allowed_models %}
    {# generate raw data overload #}
    @overload
    async def async_{{ endpoint.name }}(
        self,
        {{ endpoint_raw_params(endpoint) | indent(8) }}
    ) -> {{ build_response_type(endpoint.success_response) }}:
        ...

    {# generate model data overload #}
    {% for model in endpoint.request_body.allowed_models %}
    @overload
    async def async_{{ endpoint.name }}(
        self,
        {{ endpoint_model_params(endpoint, model) | indent(8) }}
    ) -> {{ build_response_type(endpoint.success_response) }}:
        ...

    {% endfor %}
    {% endif %}
    async def async_{{ endpoint.name }}(
        self,
        {{ endpoint_params(endpoint) | indent(8) }}
    ) -> {{ build_response_type(endpoint.success_response) }}:
        {% if endpoint.external_docs %}
        """See also: {{ endpoint.external_docs }}"""

        {% endif %}
        {{ build_request(endpoint) | indent(8) }}
        return await self._github.arequest(
            {{ build_request_params(endpoint) | indent(12) }}
        )

    {% endfor %}
